# 导入所需模块
from datetime import datetime
from functools import wraps  # 装饰器工具
from flask import jsonify, request, g, current_app,Response  # Flask请求响应工具
#from flask_jwt_extended import verify_jwt_in_request, get_jwt, get_jwt_identity  # JWT验证
from backend.models import User, db  # 用户模型和数据库实例

def api_response(data=None, code=200, message='success'):
    """统一API响应格式"""
    return jsonify({
        'code': code,          # 状态码
        'message': message,    # 提示信息
        'data': data,          # 业务数据
        'timestamp': datetime.now().isoformat()  # ISO格式时间戳
    }), code

# --- 新增: API Key 验证和配额更新辅助函数 ---
def validate_api_key_and_update_quota(apikey_value):
    """
    验证提供的 API Key，如果有效且配额充足，则扣减配额并返回 User 对象。
    否则返回 None 或 抛出异常 (这里我们返回 None 和错误消息)。
    """
    if not apikey_value:
        return None, None # 没有提供 key

    user = User.query.filter_by(apikey=apikey_value).first()

    if not user:
        # 使用 api_response 返回统一格式的错误信息
        error_response, status_code = api_response(code=403, message="无效的 API Key")
        return None, error_response

    # 检查配额 (假设 quota 为 None 表示无限配额)
    if user.quota is not None:
        if user.quota <= 0:
            error_response, status_code = api_response(code=403, message="API Key 配额不足")
            return None, error_response
        else:
            # 配额充足，扣减配额
            user.quota -= 1
            db.session.add(user) # 添加到会话
            # 注意：commit 操作最好在请求结束时统一处理，或者按需处理
            # 这里暂时先 commit，但在高并发下可能需要优化
            try:
                db.session.commit()
            except Exception as e:
                db.session.rollback()
                current_app.logger.error(f"Failed to update quota for API key {apikey_value}: {e}")
                error_response, status_code = api_response(code=500, message="更新配额时出错")
                return None, error_response

    # 验证通过，返回用户对象
    return user, None

# --- <--- 修改: 这是解决问题的关键逻辑 ---
def format_response(func):
    """响应格式化装饰器（统一处理异常和响应格式）"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            # 执行被装饰的视图函数（如get_properties）
            result = func(*args, **kwargs)

            # 检查视图函数返回的是否已经是一个打包好的Response对象
            # 这通常发生于视图函数内部调用了api_response()来处理错误时
            if isinstance(result, tuple) and len(result) == 2 and isinstance(result[0], Response):
                # 如果是，直接返回，不再进行二次包装
                return result

            # 如果不是，说明是正常的业务数据，需要我们用api_response进行包装
            result_data, status_code = result
            return api_response(data=result_data, code=status_code)

        except Exception as e:
            current_app.logger.exception("An error occurred during request processing:")
            error_msg = str(e)
            if current_app.config.get("DEBUG"):
                 error_msg = f"{type(e).__name__}: {str(e)}"
            return api_response(code=500, message=f"服务器内部错误: {error_msg}")

    return wrapper